#include "memdata.h"
#include "article.h"
#include <string>
#include <algorithm>
#include <vector>
#include <sstream>
//only for debugging
#include <iostream>


using namespace std;

namespace client_server{
	Memdata::Memdata(): ngs() {}

	Memdata::~Memdata(){
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			delete *it;
		}
	}
  
	vector<pair<int, string> > Memdata::listAllNewsGroups(){
		vector< pair<int, string> > ans;
		for(unsigned int i=0; i < ngs.size(); ++i){
			string s = ngs[i]->getNewsGroupName();
			unsigned int n = ngs[i]->getNewsGroupNumber();
			ans.push_back(make_pair(n, s));
		}
		return ans;
	}
  
	void Memdata::createNewsGroup(const string& name) throw (NewsGroupDoesNotExistException){
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			string s = (*it)->getNewsGroupName();
			if(s == name){
				throw NewsGroupDoesNotExistException();
			}
		}
		ngIncrement();
		int n = ngNum();
		ngs.push_back(new NewsGroup(name, n));
	}
    
	void Memdata::deleteNewsGroup(unsigned int id) throw (NewsGroupDoesNotExistException){
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			unsigned int ngId = (*it)->getNewsGroupNumber();
			if(ngId == id){
				ngs.erase(it);
				return;
			}
		}
		throw NewsGroupDoesNotExistException();
	}

	vector<pair<int,string> > Memdata::listAllArticles(unsigned int id) throw (NewsGroupDoesNotExistException){
		vector<pair<int, string> > names;
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			unsigned int ngId = (*it)->getNewsGroupNumber();
			if(ngId == id){
				vector<Article*> arts = (*it)->getArticles();
				vector<Article*>::iterator ait;
				for(ait = arts.begin(); ait != arts.end(); ait++){
					names.push_back(make_pair((*ait)->articlenumber(), (*ait)->articlename()));
				}
				return names;
			}
		}
		throw NewsGroupDoesNotExistException();
	}

	void Memdata::readArticle(unsigned int ngId, unsigned int aId, stringstream& ss) throw (NewsGroupDoesNotExistException, ArticleDoesNotExistException){
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			unsigned int newsgroupId = (*it)->getNewsGroupNumber();
			if(newsgroupId == ngId){
				vector<Article*> arts = (*it)->getArticles();
				vector<Article*>::iterator ait;
				for(ait = arts.begin(); ait != arts.end(); ait++){
					unsigned int articleId = (*ait)->articlenumber();
					if(articleId == aId){
						ss << (*ait)->articlename().size() << " " << (*ait)->articlename();
						ss << " " << (*ait)->articleauthor().size() << " " << (*ait)->articleauthor();
						ss << " " << (*ait)->articlecontent().size() << " " << (*ait)->articlecontent();
						return;
					}
				}
				throw ArticleDoesNotExistException();
			}
		}
		throw NewsGroupDoesNotExistException();
	}
	
	void Memdata::createArticle(unsigned int id,const string& artName,const std::string& author, const string& content) throw (NewsGroupDoesNotExistException){
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			unsigned int newsgroupId = (*it)->getNewsGroupNumber();
			if(newsgroupId == id){
				increment();
				unsigned int n = articleNum();
				(*it)->insertNewArticle(new Article(author, artName, content, n));
				return;
			}
		}
		throw NewsGroupDoesNotExistException();
	}

	void Memdata::deleteArticle(unsigned int ngId, unsigned int aId) throw (NewsGroupDoesNotExistException, ArticleDoesNotExistException ){
		vector<NewsGroup*>::iterator it;
		for(it = ngs.begin(); it != ngs.end(); it++){
			unsigned int newsgroupId = (*it)->getNewsGroupNumber();
			if(newsgroupId == ngId){
				if((*it)->deleteArticle(aId)){
					return;
				} else {
					throw ArticleDoesNotExistException();
				}
			}
		}
		throw NewsGroupDoesNotExistException();
	}
}
